import React, {useRef, useState, useContext, useEffect} from 'react';
import {Spinner} from 'reactstrap';
import XLSX from 'xlsx';

import {LedgerContext} from '../../Ledger';

import './file-input.css';

function Button({stage, select, disabled}) {
    if (disabled) {
        return <div className='button upload'>
            <div className="input-button">上传</div>
        </div>
    } else if (stage === 'PROCESS') {
        return <button className="button upload" disabled>
            <div className="input-button">
                <Spinner size="sm" /><div>后台处理中...</div>
            </div>
        </button>
    } else {
        return <div className='button upload' onClick={select}>
            <div className="input-button">上传</div>
        </div>
    }
}

function fullCase(number) {
    return Object.values(number.toString())
        .map(d => String.fromCharCode(d.charCodeAt(0) + 65248))
        .join('');
}

export default function({hidden, tableName='', dataSpecs=[], proc=()=>{}}){
    
    const [isUploading, setIsUuploading] = useState(false);
    const [stage, setStage] = useState('READY');
    const [inputKey, setInputKey] = useState(Math.random().toString(36));
    
    const [dataSpec, setDataSpec] = useState(dataSpecs.length !== 0 ? undefined : {name: tableName});

    const {books, addBook, evalBook} = useContext(LedgerContext);
    const fileRef = useRef(null);

    const switchDataSpec = (nextName) => {
        const dataSpec = dataSpecs.find(({name}) => name === nextName);
        setDataSpec(dataSpec);
    }

    useEffect(() => {
        setIsUuploading(false);
    }, [hidden]);

    const uploadFile = (e) => {
        (async () => {
            // let file = fileRef.current.files[0];
            let {files} = fileRef.current;

            const {name, withHeader=true, startingFrom} = dataSpec;
            setStage('PROCESS');
            for (let file of files) {
                const buffer = await file.arrayBuffer();
                let {Sheets, SheetNames} = XLSX.read(buffer, { type: 'array' });

                let rawData = {};
                for (let sheetName of SheetNames) {
                    rawData[sheetName] = XLSX.utils.sheet_to_json(Sheets[SheetNames[0]], {
                        header: withHeader ? undefined : 1,
                        range: startingFrom
                    });
                    if (file.name.endsWith('.csv')) {
                        console.log('csv');
                        rawData[sheetName].fromRebase = true;
                    }
                }

                try {
                    let data = proc(name, rawData, books) ?? [];
                    addBook({name: tableName, data, error:false});
                    evalBook(tableName);
                } catch (error) {
                    console.log(error); 
                    addBook({name: tableName, error: true, data: [
                        '矮油，出现错误了',
                        '如果您正在选取文件上传，请您确保所选取的文件和待上传的项目一致，重新上传或刷新页面',
                        '如果这个错误重复出现, 请联系开发人员，并提供以下错误信息:',
                        error.stack,
                        error.stack.includes('getMonth') ? '看这个错误信息估计您是上传序时账时选择了余额表' : ''
                    ]});
                    // evalBook(tableName);
                }
            }

            setInputKey(Math.random().toString(36));
            setStage('READY');

        })();
    }
    
    const toggleUploading = () => {
        setIsUuploading(!isUploading);
    }

    const selectDataElem = <select value={dataSpec?.name ?? '@'} onChange={(e) => switchDataSpec(e.target.value)}>
        {[<option key='def' value={'@'}>请按顺序选择数据</option>]
            .concat(dataSpecs.map(({name, desc}, i) => <option key={i} value={name}>{`${fullCase(i+1)}- ${desc}`}</option>))
        }
    </select>

    const uploadForm = isUploading
    ? <div key='import-form' className="upload-wrapper">
        <input
            key={inputKey} ref={fileRef}
            className='file-input' type="file"
            id="choose-backup-file" title=""
            multiple onChange={uploadFile}
            accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
        />

        {dataSpecs.length === 0 ? [] : selectDataElem}
        <Button {...{
            disabled: dataSpec === undefined,
            stage,
            select:() => {fileRef.current.click();}
        }} />
      </div>
    : <div key='import-form'></div>;

    const uploadButton = hidden
    ? <div key="import-button"></div>
    : <button key="import-button" className='button' onClick={toggleUploading}>
          {`${isUploading ? '取消导入' : '导入数据'}`}
      </button>

    return [uploadButton, uploadForm]
}
